<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>代码规范Vue篇 | Triwin</title>
    <meta name="description" content="triwin Web规范">
    <link rel="stylesheet" href="/triwin-web-inline/assets/style.d82f6ee1.css">
    <link rel="modulepreload" href="/triwin-web-inline/assets/Home.7f532832.js">
    <link rel="modulepreload" href="/triwin-web-inline/assets/app.5c149594.js">
    <link rel="modulepreload" href="/triwin-web-inline/assets/VUE3_vue.md.d53f90c9.lean.js">
    <link rel="modulepreload" href="/triwin-web-inline/assets/app.5c149594.js">
    <link rel="icon" href="/favicon.ico">
    <meta name="twitter:title" content="代码规范Vue篇 | Triwin">
    <meta property="og:title" content="代码规范Vue篇 | Triwin">
  </head>
  <body>
    <div id="app"><!--[--><div class="theme"><header class="nav-bar" data-v-675d8756><div class="sidebar-button" data-v-675d8756><svg class="icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z" class></path></svg></div><a class="nav-bar-title" href="/triwin-web-inline/" aria-label="Triwin, back to home" data-v-675d8756 data-v-4a583abe><!----> Triwin</a><div class="flex-grow" data-v-675d8756></div><div class="nav" data-v-675d8756><nav class="nav-links" data-v-675d8756 data-v-eab3edfe><!--[--><div class="item" data-v-eab3edfe><div class="nav-link" data-v-eab3edfe data-v-b8818f8c><a class="item active" href="/triwin-web-inline/VUE3/" data-v-b8818f8c>文档 <!----></a></div></div><!--]--><!----><!----></nav></div><!--[--><!--]--></header><aside class="sidebar" data-v-83e92a68><nav class="nav-links nav" data-v-83e92a68 data-v-eab3edfe><!--[--><div class="item" data-v-eab3edfe><div class="nav-link" data-v-eab3edfe data-v-b8818f8c><a class="item active" href="/triwin-web-inline/VUE3/" data-v-b8818f8c>文档 <!----></a></div></div><!--]--><!----><!----></nav><!--[--><!--]--><ul class="sidebar-links" data-v-83e92a68><!--[--><li class="sidebar-link"><p class="sidebar-link-item">数据中台前端</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/triwin-web-inline/VUE3/">基本</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item active" href="/triwin-web-inline/VUE3/vue">代码规范Vue篇</a><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="#组件名为多个单词">组件名为多个单词</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#prop-定义">Prop 定义</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#为-v-for-设置-key-值">为 v-for 设置 key 值</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#避免-v-if-和-v-for-一起使用">避免 v-if 和 v-for 一起使用</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#为组件样式设置作用域">为组件样式设置作用域</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#组件文件">组件文件</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#单文件组件文件的大小写">单文件组件文件的大小写</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#基础组件名称">基础组件名称</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#紧密耦合的组件名称">紧密耦合的组件名称</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#组件名称中的单词顺序">组件名称中的单词顺序</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#自闭合组件">自闭合组件</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#模板中的组件名称大小写">模板中的组件名称大小写</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#js-jsx-中使用的组件名称">JS/JSX 中使用的组件名称</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#完整单词的组件名称">完整单词的组件名称</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#prop-命名">Prop 命名</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#多个-attribute-的元素">多个 attribute 的元素</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#模板中的简单表达式">模板中的简单表达式</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#简单的计算属性">简单的计算属性</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#带引号的attribute值">带引号的attribute值</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#指令缩写">指令缩写</a><!----></li></ul></li><li class="sidebar-link"><a class="sidebar-link-item" href="/triwin-web-inline/VUE3/ts">代码规范TS篇</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/triwin-web-inline/VUE3/diff">细节</a><!----></li></ul></li><!--]--></ul><!--[--><!--]--></aside><!-- TODO: make this button accessible --><div class="sidebar-mask"></div><main class="page" data-v-7eddb2c4><div class="container" data-v-7eddb2c4><!--[--><!--]--><div style="position:relative;" class="content" data-v-7eddb2c4><div><h1 id="代码规范vue篇" tabindex="-1">代码规范Vue篇 <a class="header-anchor" href="#代码规范vue篇" aria-hidden="true">#</a></h1><p>本文代码规范是针对 Vue 代码的风格指南，基本大部分按照官方风格指南走，少部分涉及公司项目的部分略有不同。 <a href="https://v3.cn.vuejs.org/style-guide/#%E4%BC%98%E5%85%88%E7%BA%A7-b-%E5%BC%BA%E7%83%88%E6%8E%A8%E8%8D%90" target="_blank" rel="noopener noreferrer">官方风格指南传送门</a></p><h2 id="组件名为多个单词" tabindex="-1">组件名为多个单词 <a class="header-anchor" href="#组件名为多个单词" aria-hidden="true">#</a></h2><p><strong>组件名应该始终由多个单词组成，除了根组件 <code>App</code>，以及 <code>&lt;transition&gt;</code>、<code>&lt;component&gt;</code> 之类的 Vue 内置组件。</strong></p><p>这样做可以避免与现有以及未来的 HTML 元素<a href="https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name" target="_blank" rel="noopener noreferrer">产生冲突</a>，因为所有的 HTML 元素名称都是单个单词的。 所以最好的写法如下：</p><div class="language-js"><pre><code>app<span class="token punctuation">.</span><span class="token function">component</span><span class="token punctuation">(</span><span class="token string">&#39;todo-item&#39;</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
  <span class="token comment">// ...</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><div class="language-js"><pre><code><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">&#39;TodoItem&#39;</span><span class="token punctuation">,</span>
  <span class="token comment">// ...</span>
<span class="token punctuation">}</span>
</code></pre></div><h2 id="prop-定义" tabindex="-1">Prop 定义 <a class="header-anchor" href="#prop-定义" aria-hidden="true">#</a></h2><p><strong>Prop 定义应尽量详细</strong></p><p>在提交的代码中，prop 的定义应该尽量详细，至少指定其类型。</p><p>细致的prop 定义有两个优势：</p><ul><li>它们写明了组件的 API，所以组件的设计用法可以通俗易懂；</li><li>在开发环境下，如果为一个组件提供了格式不正确的 prop，Vue 将会告警，以帮助你捕获潜在的错误来源。</li></ul><div class="language-js"><pre><code>props<span class="token operator">:</span> <span class="token punctuation">{</span>
  status<span class="token operator">:</span> String
<span class="token punctuation">}</span>
</code></pre></div><div class="language-js"><pre><code><span class="token comment">// 更好的例子</span>
props<span class="token operator">:</span> <span class="token punctuation">{</span>
  status<span class="token operator">:</span> <span class="token punctuation">{</span>
    type<span class="token operator">:</span> String<span class="token punctuation">,</span>
    required<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>

    <span class="token function-variable function">validator</span><span class="token operator">:</span> <span class="token parameter">value</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
      <span class="token keyword">return</span> <span class="token punctuation">[</span>
        <span class="token string">&#39;syncing&#39;</span><span class="token punctuation">,</span>
        <span class="token string">&#39;synced&#39;</span><span class="token punctuation">,</span>
        <span class="token string">&#39;version-conflict&#39;</span><span class="token punctuation">,</span>
        <span class="token string">&#39;error&#39;</span>
      <span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><h2 id="为-v-for-设置-key-值" tabindex="-1">为 <code>v-for</code> 设置 key 值 <a class="header-anchor" href="#为-v-for-设置-key-值" aria-hidden="true">#</a></h2><p><strong>始终以 <code>key</code> 配合 <code>v-for</code>。</strong></p><p>v-for必须使用key，不可以漏写，并且key值必须保持唯一，我们数据比较多，key可以大大优化性能,具体可以去理解官方的虚拟DOM diff算法，这里不细说</p><div class="language-js"><pre><code><span class="token operator">&lt;</span>ul<span class="token operator">&gt;</span>
  <span class="token operator">&lt;</span>li
    v<span class="token operator">-</span><span class="token keyword">for</span><span class="token operator">=</span><span class="token string">&quot;todo in todos&quot;</span>
    <span class="token operator">:</span>key<span class="token operator">=</span><span class="token string">&quot;todo.id&quot;</span>
  <span class="token operator">&gt;</span>
    <span class="token punctuation">{</span><span class="token punctuation">{</span> todo<span class="token punctuation">.</span>text <span class="token punctuation">}</span><span class="token punctuation">}</span>
  <span class="token operator">&lt;</span><span class="token operator">/</span>li<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span><span class="token operator">/</span>ul<span class="token operator">&gt;</span>
</code></pre></div><h2 id="避免-v-if-和-v-for-一起使用" tabindex="-1">避免 <code>v-if</code> 和 <code>v-for</code> 一起使用 <a class="header-anchor" href="#避免-v-if-和-v-for-一起使用" aria-hidden="true">#</a></h2><p><strong>永远不要在一个元素上同时使用 <code>v-if</code> 和 <code>v-for</code>。</strong></p><p>一般我们在两种常见的情况下会倾向于这样做：</p><ul><li><p>为了对列表中的项目进行过滤 (比如 <code>v-for=&quot;user in users&quot; v-if=&quot;user.isActive&quot;</code>)。在这种情形下，请将 <code>users</code> 替换为一个计算属性 (比如 <code>activeUsers</code>)，返回过滤后的列表。</p></li><li><p>为了避免渲染本应该被隐藏的列表 (比如 <code>v-for=&quot;user in users&quot; v-if=&quot;shouldShowUsers&quot;</code>)。这种情形下，请将 <code>v-if</code> 移动至容器元素上 (比如 <code>ul</code>、<code>ol</code>)。</p></li></ul><p>当 Vue 处理指令时，<code>v-if</code> 比 <code>v-for</code> 具有更高的优先级，所以这个模板：</p><div class="language-html"><pre><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ul</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span>
    <span class="token attr-name">v-for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>user in users<span class="token punctuation">&quot;</span></span>
    <span class="token attr-name">v-if</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>user.isActive<span class="token punctuation">&quot;</span></span>
    <span class="token attr-name">:key</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>user.id<span class="token punctuation">&quot;</span></span>
  <span class="token punctuation">&gt;</span></span>
    {{ user.name }}
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ul</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>将抛出一个错误，因为 <code>v-if</code> 指令将首先被执行，而迭代的变量 <code>user</code> 此时还不存在。</p><p>这可以通过遍历一个计算属性来解决，像这样：</p><div class="language-js"><pre><code>computed<span class="token operator">:</span> <span class="token punctuation">{</span>
  <span class="token function">activeUsers</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>users<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token parameter">user</span> <span class="token operator">=&gt;</span> user<span class="token punctuation">.</span>isActive<span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><div class="language-html"><pre><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ul</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span>
    <span class="token attr-name">v-for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>user in activeUsers<span class="token punctuation">&quot;</span></span>
    <span class="token attr-name">:key</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>user.id<span class="token punctuation">&quot;</span></span>
  <span class="token punctuation">&gt;</span></span>
    {{ user.name }}
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ul</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>另外，我们也可以使用 <code>&lt;template&gt;</code> 标签和 <code>v-for</code> 来包裹 <code>&lt;li&gt;</code> 元素。</p><div class="language-html"><pre><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ul</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span> <span class="token attr-name">v-for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>user in users<span class="token punctuation">&quot;</span></span> <span class="token attr-name">:key</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>user.id<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span> <span class="token attr-name">v-if</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>user.isActive<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      {{ user.name }}
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ul</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-html"><pre><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ul</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span>
    <span class="token attr-name">v-for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>user in activeUsers<span class="token punctuation">&quot;</span></span>
    <span class="token attr-name">:key</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>user.id<span class="token punctuation">&quot;</span></span>
  <span class="token punctuation">&gt;</span></span>
    {{ user.name }}
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ul</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-html"><pre><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ul</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span> <span class="token attr-name">v-for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>user in users<span class="token punctuation">&quot;</span></span> <span class="token attr-name">:key</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>user.id<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span> <span class="token attr-name">v-if</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>user.isActive<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      {{ user.name }}
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ul</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><h2 id="为组件样式设置作用域" tabindex="-1">为组件样式设置作用域 <a class="header-anchor" href="#为组件样式设置作用域" aria-hidden="true">#</a></h2><p><strong>对于应用来说，样式在顶层 <code>App</code> 组件和布局组件中可以是全局的，但是在其它所有组件中都应该是有作用域的。</strong></p><p>所以写的时候记得加上scoped：</p><div class="language-html"><pre><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>button button-close<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>×<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>

<span class="token comment">&lt;!-- 使用 `scoped` attribute --&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span> <span class="token attr-name">scoped</span><span class="token punctuation">&gt;</span></span><span class="token style"><span class="token language-css">
<span class="token selector">.button</span> <span class="token punctuation">{</span>
  <span class="token property">border</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
  <span class="token property">border-radius</span><span class="token punctuation">:</span> 2px<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token selector">.button-close</span> <span class="token punctuation">{</span>
  <span class="token property">background-color</span><span class="token punctuation">:</span> red<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>或者按照BEM规定方式来约束样式</p><div class="language-html"><pre><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>c-Button c-Button--close<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>×<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>

<span class="token comment">&lt;!-- 使用 BEM 约定 --&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span><span class="token punctuation">&gt;</span></span><span class="token style"><span class="token language-css">
<span class="token selector">.c-Button</span> <span class="token punctuation">{</span>
  <span class="token property">border</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
  <span class="token property">border-radius</span><span class="token punctuation">:</span> 2px<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token selector">.c-Button--close</span> <span class="token punctuation">{</span>
  <span class="token property">background-color</span><span class="token punctuation">:</span> red<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><h2 id="组件文件" tabindex="-1">组件文件 <a class="header-anchor" href="#组件文件" aria-hidden="true">#</a></h2><p><strong>只要有能够拼接文件的构建系统，就把每个组件单独分成文件。</strong></p><p>当你需要编辑一个组件，或查阅一个组件的用法时，这种做法可以帮助你更快速地找到它。</p><div class="language-"><pre><code>components/
|- TodoList.js
|- TodoItem.js
</code></pre></div><div class="language-"><pre><code>components/
|- TodoList.vue
|- TodoItem.vue
</code></pre></div><h2 id="单文件组件文件的大小写" tabindex="-1">单文件组件文件的大小写 <a class="header-anchor" href="#单文件组件文件的大小写" aria-hidden="true">#</a></h2><p><strong>单文件组件 的文件名应该始终是单词大写开头 (PascalCase)</strong></p><div class="language-"><pre><code>components/
|- MyComponent.vue
</code></pre></div><h2 id="基础组件名称" tabindex="-1">基础组件名称 <a class="header-anchor" href="#基础组件名称" aria-hidden="true">#</a></h2><p><strong>应用特定样式和约定的基础组件 (也就是展示类的、无逻辑的或无状态的组件) 应该全部以一个特定的前缀开头，比如 <code>Base</code>、<code>App</code> 或 <code>V</code>。</strong></p><p>这些组件为你的应用奠定了一致的基础样式和行为。它们可能<strong>只</strong>包括：</p><ul><li>HTML 元素</li><li>其它基础组件</li><li>第三方 UI 组件</li></ul><p>但是它们<strong>绝不会</strong>包括全局状态 (比如来自 Vuex store)。</p><p>它们的名字通常包含所包裹元素的名字 (比如 <code>BaseButton</code>、<code>BaseTable</code>)，除非没有现成的对应功能的元素 (比如 <code>BaseIcon</code>)。如果你为特定的上下文构建类似的组件，那它们几乎总会消费这些组件 (比如 <code>BaseButton</code> 可能会用在 <code>ButtonSubmit</code> 上)。</p><p>简单来说，就是通用型组件比如 基础按钮：名称是 Base + Button 然后这个按钮在全局通用</p><div class="language-js"><pre><code><span class="token comment">//注册全局组件</span>
<span class="token keyword">const</span> requireComponent <span class="token operator">=</span> require<span class="token punctuation">.</span><span class="token function">context</span><span class="token punctuation">(</span><span class="token string">&quot;./src&quot;</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">Base[A-Z]\w+\.(vue|js)$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">)</span>
requireComponent<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">fileName</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">let</span> baseComponentConfig <span class="token operator">=</span> <span class="token function">requireComponent</span><span class="token punctuation">(</span>fileName<span class="token punctuation">)</span>
  baseComponentConfig <span class="token operator">=</span> baseComponentConfig<span class="token punctuation">.</span>default <span class="token operator">||</span> baseComponentConfig
  <span class="token keyword">const</span> baseComponentName <span class="token operator">=</span> baseComponentConfig<span class="token punctuation">.</span>name <span class="token operator">||</span> <span class="token punctuation">(</span>
    fileName
      <span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^.+\/</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">,</span> <span class="token string">&#39;&#39;</span><span class="token punctuation">)</span>
      <span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">\.\w+$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">,</span> <span class="token string">&#39;&#39;</span><span class="token punctuation">)</span>
  <span class="token punctuation">)</span>
  app<span class="token punctuation">.</span><span class="token function">component</span><span class="token punctuation">(</span>baseComponentName<span class="token punctuation">,</span> baseComponentConfig<span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><p>命名举例</p><div class="language-"><pre><code>components/
|- BaseButton.vue
|- BaseTable.vue
|- BaseIcon.vue
</code></pre></div><div class="language-"><pre><code>components/
|- AppButton.vue
|- AppTable.vue
|- AppIcon.vue
</code></pre></div><div class="language-"><pre><code>components/
|- VButton.vue
|- VTable.vue
|- VIcon.vue
</code></pre></div><h2 id="紧密耦合的组件名称" tabindex="-1">紧密耦合的组件名称 <a class="header-anchor" href="#紧密耦合的组件名称" aria-hidden="true">#</a></h2><p><strong>与父组件紧密耦合的子组件应该以父组件名作为前缀命名。</strong></p><p>如果一个组件只在某个特定父组件的上下文中有意义，那么这层关系应该体现在其命名上。因为编辑器通常会按字母顺序组织文件，这么做也可以把相关联的文件排放在一起。</p><div class="language-"><pre><code>components/
|- TodoList.vue
|- TodoListItem.vue
|- TodoListItemButton.vue
</code></pre></div><div class="language-"><pre><code>components/
|- SearchSidebar.vue
|- SearchSidebarNavigation.vue
</code></pre></div><h2 id="组件名称中的单词顺序" tabindex="-1">组件名称中的单词顺序 <a class="header-anchor" href="#组件名称中的单词顺序" aria-hidden="true">#</a></h2><p><strong>组件名称应该以高阶的 (通常是一般化描述的) 单词开头，并以描述性的修饰词结尾。</strong></p><p>同样要注意<strong>在你的应用中所谓的“高阶”是跟语境有关的</strong>。 所以我们要做到能简单直接的了解组件是干什么的，就应该这样命名：</p><div class="language-"><pre><code>components/
|- SearchButtonClear.vue
|- SearchButtonRun.vue
|- SearchInputExcludeGlob.vue
|- SearchInputQuery.vue
|- SettingsCheckboxLaunchOnStartup.vue
|- SettingsCheckboxTerms.vue
</code></pre></div><p>因为编辑器通常会按字母顺序组织文件，所以现在组件之间的重要关系一目了然。</p><p>如果项目中的某个功能模块需要处理组件过多，那么请单独给他定义一个文件夹进行处理</p><div class="language-"><pre><code>components/
|- Search/
|-- SearchButtonClear.vue
|-- SearchButtonRun.vue
|-- SearchInputQuery.vue
|-- SearchInputExcludeGlob.vue
|-- SettingsCheckboxTerms.vue
|-- SettingsCheckboxLaunchOnStartup.vue
</code></pre></div><h2 id="自闭合组件" tabindex="-1">自闭合组件 <a class="header-anchor" href="#自闭合组件" aria-hidden="true">#</a></h2><p><strong>在单文件组件、字符串模板和 JSX 中，没有内容的组件应该是自闭合的——但在 DOM 模板里永远不要这样做。</strong></p><div class="language-html"><pre><code><span class="token comment">&lt;!-- 在单文件组件、字符串模板和 JSX 中 --&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>MyComponent</span><span class="token punctuation">/&gt;</span></span>
</code></pre></div><h2 id="模板中的组件名称大小写" tabindex="-1">模板中的组件名称大小写 <a class="header-anchor" href="#模板中的组件名称大小写" aria-hidden="true">#</a></h2><p><strong>在 单文件组件 和字符串模板中，组件名称应该始终是 PascalCase 的。</strong></p><div class="language-html"><pre><code><span class="token comment">&lt;!-- 在单文件组件和字符串模板中 --&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>MyComponent</span><span class="token punctuation">/&gt;</span></span>
</code></pre></div><h2 id="js-jsx-中使用的组件名称" tabindex="-1">JS/JSX 中使用的组件名称 <a class="header-anchor" href="#js-jsx-中使用的组件名称" aria-hidden="true">#</a></h2><p><strong>JS/ JSX 中的组件名应该始终是 PascalCase 的</strong></p><div class="language-js"><pre><code><span class="token keyword">import</span> MyComponent <span class="token keyword">from</span> <span class="token string">&#39;./MyComponent.vue&#39;</span>
</code></pre></div><div class="language-js"><pre><code><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">&#39;MyComponent&#39;</span><span class="token punctuation">,</span>
  <span class="token comment">// ...</span>
<span class="token punctuation">}</span>
</code></pre></div><h2 id="完整单词的组件名称" tabindex="-1">完整单词的组件名称 <a class="header-anchor" href="#完整单词的组件名称" aria-hidden="true">#</a></h2><p><strong>组件名称应该倾向于完整的单词，而不是缩写。</strong></p><p>编辑器中的自动补全已经让书写长命名的代价非常之低了，而其带来的明确性却是非常宝贵的。不常用的缩写尤其应该避免。</p><div class="language-"><pre><code>components/
|- StudentDashboardSettings.vue
|- UserProfileOptions.vue
</code></pre></div><h2 id="prop-命名" tabindex="-1">Prop 命名 <a class="header-anchor" href="#prop-命名" aria-hidden="true">#</a></h2><p><strong>在声明 prop 的时候，其命名应该始终使用 camelCase，而在模板和 JSX 中应该始终使用 kebab-case。</strong></p><p>我们只是单纯地遵循了每种语言的约定。在 JavaScript 中 camelCase 更为自然。而在 HTML 中则是 kebab-case。</p><div class="language-js"><pre><code>props<span class="token operator">:</span> <span class="token punctuation">{</span>
  greetingText<span class="token operator">:</span> String
<span class="token punctuation">}</span>
</code></pre></div><div class="language-html"><pre><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>WelcomeMessage</span> <span class="token attr-name">greeting-text</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>hi<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>
</code></pre></div><h2 id="多个-attribute-的元素" tabindex="-1">多个 attribute 的元素 <a class="header-anchor" href="#多个-attribute-的元素" aria-hidden="true">#</a></h2><p><strong>多个 attribute 的元素应该分多行撰写，每个 attribute 一行。</strong></p><p>在 JavaScript 中，用多行分隔对象的多个 property 是很常见的最佳实践，因为这样更易读。模板和 JSX 都需要做同样的考量。</p><div class="language-html"><pre><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>MyComponent</span>
  <span class="token attr-name">foo</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>a<span class="token punctuation">&quot;</span></span>
  <span class="token attr-name">bar</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>b<span class="token punctuation">&quot;</span></span>
  <span class="token attr-name">baz</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>c<span class="token punctuation">&quot;</span></span>
<span class="token punctuation">/&gt;</span></span>
</code></pre></div><h2 id="模板中的简单表达式" tabindex="-1">模板中的简单表达式 <a class="header-anchor" href="#模板中的简单表达式" aria-hidden="true">#</a></h2><p><strong>组件模板应该只包含简单的表达式，复杂的表达式则应该重构为计算属性或方法。</strong></p><p>复杂表达式会让你的模板变得不那么声明式。我们应该尽量描述应该显示<em>什么</em>，而非<em>如何</em>计算那个值。而且计算属性和方法使得代码可以复用。</p><div class="language-html"><pre><code><span class="token comment">&lt;!-- 在模板中 --&gt;</span>
{{ normalizedFullName }}
</code></pre></div><div class="language-js"><pre><code><span class="token comment">// 复杂表达式已经转为了一个计算属性</span>
computed<span class="token operator">:</span> <span class="token punctuation">{</span>
  <span class="token function">normalizedFullName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>fullName<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">&#39; &#39;</span><span class="token punctuation">)</span>
      <span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token parameter">word</span> <span class="token operator">=&gt;</span> word<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">toUpperCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> word<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
      <span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">&#39; &#39;</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><h2 id="简单的计算属性" tabindex="-1">简单的计算属性 <a class="header-anchor" href="#简单的计算属性" aria-hidden="true">#</a></h2><p><strong>应该把复杂计算属性尽可能多地分割为更简单的计算属性。</strong></p><p>更简单的、命名得当的计算属性：</p><ul><li><p><strong>更易于测试</strong></p><p>当每个计算属性都仅包含一个非常简单，且依赖很少的表达式时，撰写测试以确保其能够正确地工作就会变得容易许多。</p></li><li><p><strong>更易于阅读</strong></p><p>简化计算属性要求你为每一个值都起一个描述性的名称，即便它并没有被复用。这使得其他开发者 (以及未来的你) 更容易专注于他们所关心的代码，并了解现状。</p></li><li><p><strong>更好地“拥抱变化”</strong></p><p>任何能够被命名的值，都有可能被用在视图上。举个例子，我们可能打算展示一个信息，告诉用户他们节省了多少钱。也可能打算计算税费，但是也许会分开展现，而不是作为总价的一部分。</p><p>小且专注的计算属性对信息将如何被使用所作出的假设更少，因此当需求变更时，重构的工作量也将更小。</p></li></ul><div class="language-js"><pre><code>computed<span class="token operator">:</span> <span class="token punctuation">{</span>
  <span class="token function">basePrice</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>manufactureCost <span class="token operator">/</span> <span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">-</span> <span class="token keyword">this</span><span class="token punctuation">.</span>profitMargin<span class="token punctuation">)</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>

  <span class="token function">discount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>basePrice <span class="token operator">*</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>discountPercent <span class="token operator">||</span> <span class="token number">0</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>

  <span class="token function">finalPrice</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>basePrice <span class="token operator">-</span> <span class="token keyword">this</span><span class="token punctuation">.</span>discount
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><h2 id="带引号的attribute值" tabindex="-1">带引号的attribute值 <a class="header-anchor" href="#带引号的attribute值" aria-hidden="true">#</a></h2><p><strong>非空 HTML attribute 的值应该始终带有引号 (单引号或双引号，选择未在 JS 里面使用的那个)。</strong></p><p>虽然在 HTML 中不带空格的 attribute 的值是可以不加引号的，但这样做往往导致大家<em>避开</em>空格，从而使得 attribute 的可读性变差。</p><div class="language-html"><pre><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>text<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-html"><pre><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>AppSidebar</span> <span class="token attr-name">:style</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>{ width: sidebarWidth + <span class="token punctuation">&#39;</span>px<span class="token punctuation">&#39;</span> }<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
</code></pre></div><h2 id="指令缩写" tabindex="-1">指令缩写 <a class="header-anchor" href="#指令缩写" aria-hidden="true">#</a></h2><p><strong>指令缩写 (用 <code>:</code> 表示 <code>v-bind:</code>，<code>@</code> 表示 <code>v-on:</code> 和用 <code>#</code> 表示 <code>v-slot</code>) 全部使用缩写的方式</strong></p><div class="language-html"><pre><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span>
  <span class="token attr-name">:value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>newTodoText<span class="token punctuation">&quot;</span></span>
  <span class="token attr-name">:placeholder</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>newTodoInstructions<span class="token punctuation">&quot;</span></span>
<span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-html"><pre><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span>
  <span class="token attr-name">@input</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>onInput<span class="token punctuation">&quot;</span></span>
  <span class="token attr-name">@focus</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>onFocus<span class="token punctuation">&quot;</span></span>
<span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-html"><pre><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span> <span class="token attr-name">#header</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">&gt;</span></span>Here might be a page title<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span> <span class="token attr-name">#footer</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>Here&#39;s some contact info<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
</code></pre></div></div></div><footer class="page-footer" data-v-7eddb2c4 data-v-fb8d84c6><div class="edit" data-v-fb8d84c6><div class="edit-link" data-v-fb8d84c6 data-v-1ed99556><!----></div></div><div class="updated" data-v-fb8d84c6><!----></div></footer><div class="next-and-prev-link" data-v-7eddb2c4 data-v-38ede35f><div class="container" data-v-38ede35f><div class="prev" data-v-38ede35f><a class="link" href="/triwin-web-inline/VUE3/" data-v-38ede35f><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="icon icon-prev" data-v-38ede35f><path d="M19,11H7.4l5.3-5.3c0.4-0.4,0.4-1,0-1.4s-1-0.4-1.4,0l-7,7c-0.1,0.1-0.2,0.2-0.2,0.3c-0.1,0.2-0.1,0.5,0,0.8c0.1,0.1,0.1,0.2,0.2,0.3l7,7c0.2,0.2,0.5,0.3,0.7,0.3s0.5-0.1,0.7-0.3c0.4-0.4,0.4-1,0-1.4L7.4,13H19c0.6,0,1-0.4,1-1S19.6,11,19,11z"></path></svg><span class="text" data-v-38ede35f>基本</span></a></div><div class="next" data-v-38ede35f><a class="link" href="/triwin-web-inline/VUE3/ts" data-v-38ede35f><span class="text" data-v-38ede35f>代码规范TS篇</span><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="icon icon-next" data-v-38ede35f><path d="M19.9,12.4c0.1-0.2,0.1-0.5,0-0.8c-0.1-0.1-0.1-0.2-0.2-0.3l-7-7c-0.4-0.4-1-0.4-1.4,0s-0.4,1,0,1.4l5.3,5.3H5c-0.6,0-1,0.4-1,1s0.4,1,1,1h11.6l-5.3,5.3c-0.4,0.4-0.4,1,0,1.4c0.2,0.2,0.5,0.3,0.7,0.3s0.5-0.1,0.7-0.3l7-7C19.8,12.6,19.9,12.5,19.9,12.4z"></path></svg></a></div></div></div><!--[--><!--]--></div></main></div><!----><!--]--></div>
    <script>__VP_HASH_MAP__ = JSON.parse("{\"vue3_diff.md\":\"1e05b574\",\"vue3_index.md\":\"8f5c37c3\",\"vue3_ts.md\":\"22aafe44\",\"vue3_vue.md\":\"d53f90c9\",\"index.md\":\"1651360c\"}")</script>
    <script type="module" async src="/triwin-web-inline/assets/app.5c149594.js"></script>
    
  </body>
</html>